/*
 *
 *  Copyright (C) 2009 GSyC/LibreSoft
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Roberto Calvo Palomino <rocapal@gsyc.es>
 *
 */

package com.LibreGeoSocial.App.Resources;

import java.util.ArrayList;
import java.util.Collections;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.LibreGeoSocial.Api.Audio;
import com.LibreGeoSocial.Api.GeoNode;
import com.LibreGeoSocial.Api.GeoNodePositionComparator;
import com.LibreGeoSocial.Api.LibreGeoSocial;
import com.LibreGeoSocial.Api.Note;
import com.LibreGeoSocial.Api.Photo;
import com.LibreGeoSocial.Api.User;
import com.LibreGeoSocial.App.R;
import com.LibreGeoSocial.App.ViewMap;
import com.LibreGeoSocial.App.AR.ARView;
import com.LibreGeoSocial.App.Routes.LocationService;
import com.LibreGeoSocial.App.Utils.LocationUtils;

public class ResourceLGS extends ListActivity {
	
	
	PhotoAdapter mAdapter; 
	
	static ArrayList<GeoNode> resourceList, aux;
	
	private static final int MENU_SEARCH = Menu.FIRST + 1;
	private static final int MENU_DISTANCE = Menu.FIRST + 2;
	private static final int MENU_DISTANCE_0 = Menu.FIRST + 3;
	private static final int MENU_DISTANCE_1 = Menu.FIRST + 4;
	private static final int MENU_DISTANCE_5 = Menu.FIRST + 5;
	private static final int MENU_DISTANCE_10 = Menu.FIRST + 6;
	private static final int MENU_DISTANCE_50 = Menu.FIRST + 7;

	private static final int MENU_SEE_CAM = Menu.FIRST + 8;

	private static final int DIALOG_SEARCH = 1;
	private static final int DIALOG_PBAR = 2;

	public static final String LGS_RESOURCE = "lgs_resource";
	
	private String mPattern;
	private Double mDistance;
	
	private boolean mSemanticSearch = false; 
	
	private Handler handlerEnd = new Handler() {
		@Override
		public void handleMessage(Message msg) {

	        mAdapter.notifyDataSetChanged();
			removeDialog(DIALOG_PBAR);
		}
	};
	
	public void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		    
		mPattern = null;
		mDistance = 2.0;
		
  		// Adapter for ListView
        mAdapter = new PhotoAdapter(ResourceLGS.this);
        setListAdapter(mAdapter);
        
		if(resourceList == null)
			loadResources();
		else if( resourceList.isEmpty() )
			loadResources();

	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event){
		
		if(keyCode == KeyEvent.KEYCODE_BACK)
			resourceList.clear();
		
		return super.onKeyDown(keyCode, event);
	}
	
	private void loadResources(){
		showDialog(DIALOG_PBAR);
		new Thread(){
			public void run(){
				setResources();
				handlerEnd.sendEmptyMessage(0);
			}
		}.start();
	}
	
	private void setResources ()
	{
		
		Intent i = getIntent();

		Integer groupId  = i.getIntExtra("group", Integer.MIN_VALUE);
		
		if (groupId != Integer.MIN_VALUE)
		{		
			// Elements group Activity
			resourceList = LibreGeoSocial.getInstance().getElementsGroup(groupId);
		}
		else
		{
			// Resource LGS Activity (Search)
			if (mSemanticSearch)
			{
				resourceList = LibreGeoSocial.getInstance().sematingSearch(mPattern);
			}	
			else
			{
				resourceList = LibreGeoSocial.getInstance().searchAllNodes(mDistance,mPattern);
			}
			
		}
		// Sort the list by distance
		GeoNodePositionComparator comparator = new GeoNodePositionComparator();
		Collections.sort(resourceList, comparator);
		
	}
	
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	
		if ( getIntent().getIntExtra("group", Integer.MIN_VALUE) == Integer.MIN_VALUE )
		{
	        super.onCreateOptionsMenu(menu);
	        
	        menu.add(0, MENU_SEARCH, 0, "Search to ...")
	        		.setIcon(R.drawable.search_48)
	                .setAlphabeticShortcut('A');
	                
	        SubMenu sub = menu.addSubMenu(0, MENU_DISTANCE, 0, "Distance")
											.setIcon(R.drawable.image_48);
	        
	        sub.add(0,MENU_DISTANCE_0,0, "500 m");
	        sub.add(0,MENU_DISTANCE_1,0, "1 Km");
	        sub.add(0,MENU_DISTANCE_5,0, "5 Km");
	        sub.add(0,MENU_DISTANCE_10,0,"10 Km");
	        sub.add(0,MENU_DISTANCE_50,0,"50 Km");
	
	        menu.add(0, MENU_SEE_CAM, 0, "Real View")
	        		.setIcon(R.drawable.real_view);
		}
        return true;
    }
	
	
    @Override
    public boolean onOptionsItemSelected (MenuItem item) {
    	
    	switch (item.getItemId()) {
    	
    		case MENU_SEARCH:
    		
    			showDialog(DIALOG_SEARCH);
    			
    			break;    			
    			
    		case MENU_DISTANCE_0:
    			
    			mDistance = 0.5;
    			setResources();
    			mAdapter.notifyDataSetChanged();
    			break;
    			
    		case MENU_DISTANCE_1:
    			
    			mDistance = 1.0;
    			setResources();
    			mAdapter.notifyDataSetChanged();
    			break;
    	
    		case MENU_DISTANCE_5:
    			
    			mDistance = 5.0;
    			setResources();
    			mAdapter.notifyDataSetChanged();
    			break;
    			
    		case MENU_DISTANCE_10:
    			
    			mDistance = 10.0;
    			setResources();
    			mAdapter.notifyDataSetChanged();
    			break;
    		
    		case MENU_DISTANCE_50:
    			
    			mDistance = 50.0;
    			setResources();
    			mAdapter.notifyDataSetChanged();
    			break;
    			
    		case MENU_SEE_CAM:
    			
    			Intent i = new Intent(this, ARView.class);
    	    	
    			i.putExtra("RESOURCE_TYPE", LGS_RESOURCE);
    			i.putExtra("LGS_DISTANCE", mDistance);
    			i.putExtra("LGS_PATTERN", mPattern);
    			i.putExtra("LGS_RESOURCE_LIST", resourceList);
    			
    	    	startActivity(i);
    			
    			break;
    	}
    			  
    	return super.onOptionsItemSelected(item);
    }
	
    
protected Dialog onCreateDialog(int id) {
        
    	switch (id) {
	    	case DIALOG_SEARCH:
	    		
	    		LayoutInflater factory = LayoutInflater.from(this);
	    		final View textEntryView = factory.inflate(R.layout.search, null);
	    		
	    		final EditText edit = (EditText) textEntryView.findViewById (R.id.txtSearch);
	    		final TextView title = (TextView) textEntryView.findViewById (R.id.state_view);
	    		final CheckBox cbSemantic = (CheckBox) textEntryView.findViewById (R.id.cbSemantic);
	    		edit.setText("");
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("Search to ...")
		        .setView(textEntryView)
		        .setPositiveButton("Search", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	
		            	
		            	mSemanticSearch = cbSemantic.isChecked(); 		            	
	            		
		            	mPattern = edit.getText().toString();		        		
		            	setResources();
		            	
		            	mAdapter.notifyDataSetChanged();
		            	
		            }
		        })
		        .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		
		                /* User clicked cancel so do some stuff */
		            }
		        })
		        .create();
		        
	    	case DIALOG_PBAR:
	    		ProgressDialog dialog = new ProgressDialog(this);
	    		dialog.setMessage("Loading...");
	    		dialog.setIndeterminate(true);
	    		dialog.setCancelable(true);
	    		return dialog;
		    
    	}
    	
    	return null;
    }
	
    protected void onListItemClick(ListView l, View v, int position, long id) {
    	
    	GeoNode myNode = resourceList.get(position);

    	Intent i = new Intent(this, ViewMap.class);
    	
    	i.putExtra("latitude",myNode.getLatitude());
    	i.putExtra("longitude",myNode.getLongitude());
    	i.putExtra("url","");
    	
    	startActivity(i);
    
	}
	
 
    
	public static class PhotoAdapter extends BaseAdapter {

		private Context mContext;
		
		public PhotoAdapter(Context c) {
            mContext = c;
        }

		public int getCount() {
			// TODO Auto-generated method stub
			if(resourceList == null)
				return 0;
			return resourceList.size();
		}

		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View view;
			
	        if (convertView == null) {
	            // Make up a new view
	            LayoutInflater inflater = (LayoutInflater) mContext
	                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	            view = inflater.inflate(R.layout.generic_list, null);
	        } else {
	            // Use convertView if it is available
	            view = convertView;
	        }
			
	        
	        ImageView img = (ImageView) view.findViewById(R.id.image);
	        
	        GeoNode myResource = resourceList.get(position);
	        String title = null;
	        String description = null;
	        
			// FIXME: Refactor with other class
	        
	        // Calculate distance			
	        String distString = "";
			
			if ( myResource.getLatitude()==-1.0 && 
					myResource.getLongitude()==-1.0)
			{
				distString = "Unknow Location";
			}
			else if (LocationService.getCurrentLocation() == null)
				distString = "Unknow Location";
			else
			{
				// Calculate distance
				float dist = LocationUtils.calculateDistance (LocationService.getCurrentLocation(), 
															  myResource.getLocation());
				
				distString = LocationUtils.displayDistance(dist, LocationUtils.AUTO);
			}			
	        
	        if ( Photo.class.isInstance(myResource) )    	
	        {
	        	Photo myphoto = (Photo) resourceList.get(position);
	        	img.setImageBitmap(myphoto.getBitmapImageThumb());
	        	title = myphoto.getName();
	        	description = "Dist: " + distString + "\n" + myphoto.getDescription();
	        	
	        }
	        else if (Note.class.isInstance(myResource) )
	        {
	        	Note mynote = (Note) resourceList.get(position);
	        	img.setImageResource(R.drawable.paper_pencil_48);	 
	        	title = mynote.getTitle();
	        	description = "Dist: " + distString + "\n" + mynote.getBody();
	        	
	        }
	        else if ( User.class.isInstance(myResource))
	        {
	        	User myuser = (User) resourceList.get(position);
	        	img.setImageResource(R.drawable.user_48);
	        	title = myuser.getName() + " (" + myuser.getUsername() +")";
	        	description =  distString + " - " + myuser.getState();
	        }
	        else if (Audio.class.isInstance(myResource) )
	        {
	        	Audio mysound = (Audio) resourceList.get(position);
	        	img.setImageResource(R.drawable.audio_48);	 
	        	title = mysound.getName();
	        	description = "Dist: " + distString + "\n" + mysound.getDescription();
	        	
	        }

	        
	        TextView t = (TextView) view.findViewById(R.id.title);
	        t.setText(title);	    
			
			t = (TextView) view.findViewById(R.id.owner);
			t.setText(description);
			
			return view;
	        
		}

	}



}
